using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using MySqlConnector;
using System.Text.Json;
using System.Text.Json.Serialization;
using FinData.Services;
using System.Net.Http;
using System.Linq;

namespace FinData.Controllers
{
    [ApiController]
    [Route("api")]
    public class FavoritesController : ControllerBase
    {
        private readonly DatabaseService _databaseService;
        private readonly TradingCalendarService _calendarService;

        public class FavoriteStock
        {
            public string Code { get; set; }
            public string Name { get; set; }
        }

        public class AddFavoriteRequest
        {
            public string StockCode { get; set; }
            public string StockName { get; set; }
        }

        public FavoritesController(DatabaseService databaseService, TradingCalendarService calendarService)
        {
            _databaseService = databaseService;
            _calendarService = calendarService;
        }

        [HttpGet("favorites")]
        public async Task<IActionResult> GetFavorites()
        {
            // 检查用户是否已登录
            bool isLoggedIn = HttpContext.Session.GetInt32("UserId") != null;
            
            // 如果未登录，返回空列表和登录状态
            if (!isLoggedIn)
            {
                return Ok(new { 
                    favorites = new List<FavoriteStock>(),
                    isLoggedIn = false,
                    message = "您当前未登录，自选数据将不会保存"
                });
            }

            int userId = HttpContext.Session.GetInt32("UserId").Value;
            var favorites = new List<FavoriteStock>();

            try
            {
                using (var connection = _databaseService.GetConnection())
                {
                    await connection.OpenAsync();

                    // 创建自选股票表（如果不存在）
                    string createTableQuery = @"
                        CREATE TABLE IF NOT EXISTS favorites (
                            id INT AUTO_INCREMENT PRIMARY KEY,
                            user_id INT NOT NULL,
                            stock_code VARCHAR(10) NOT NULL,
                            stock_name VARCHAR(50),
                            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                            UNIQUE KEY user_stock (user_id, stock_code),
                            FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
                        )";

                    using (var command = new MySqlCommand(createTableQuery, connection))
                    {
                        await command.ExecuteNonQueryAsync();
                    }

                    // 获取用户的自选股票
                    string query = "SELECT stock_code, stock_name FROM favorites WHERE user_id = @UserId";
                    using (var command = new MySqlCommand(query, connection))
                    {
                        command.Parameters.AddWithValue("@UserId", userId);
                        
                        using (var reader = await command.ExecuteReaderAsync())
                        {
                            while (await reader.ReadAsync())
                            {
                                favorites.Add(new FavoriteStock
                                {
                                    Code = reader.GetString("stock_code"),
                                    Name = reader.IsDBNull(reader.GetOrdinal("stock_name")) ? null : reader.GetString("stock_name")
                                });
                            }
                        }
                    }
                }

                return Ok(new { 
                    favorites = favorites,
                    isLoggedIn = true
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取自选股票失败: {ex.Message}");
                return StatusCode(500, new { message = "获取自选股票失败，请重试" });
            }
        }

        [HttpPost("add-favorite")]
        public async Task<IActionResult> AddFavorite([FromBody] AddFavoriteRequest request)
        {
            // 检查用户是否已登录
            if (HttpContext.Session.GetInt32("UserId") == null)
            {
                return Unauthorized(new { message = "请先登录" });
            }

            if (string.IsNullOrEmpty(request.StockCode))
            {
                return BadRequest(new { message = "股票代码不能为空" });
            }

            int userId = HttpContext.Session.GetInt32("UserId").Value;
            string stockCode = request.StockCode;
            string stockName = request.StockName ?? "";

            try
            {
                // 验证股票代码格式
                if (!System.Text.RegularExpressions.Regex.IsMatch(stockCode, @"^\d{6}$"))
                {
                    return BadRequest(new { message = "股票代码格式不正确" });
                }

                // 如果没有提供股票名称，尝试获取
                if (string.IsNullOrEmpty(stockName))
                {
                    try
                    {
                        // 判断股票市场
                        string market;
                        if (stockCode.StartsWith("60") || stockCode.StartsWith("68"))
                        {
                            market = "sh"; // 上海证券交易所
                        }
                        else if (stockCode.StartsWith("00") || stockCode.StartsWith("30"))
                        {
                            market = "sz"; // 深圳证券交易所
                        }
                        else
                        {
                            market = "bj"; // 北京证券交易所
                        }
                        
                        string fullCode = $"{market}{stockCode}";

                        // 使用HttpClient请求腾讯财经API获取股票信息
                        using (var httpClient = new HttpClient())
                        {
                            string url = $"https://qt.gtimg.cn/q={fullCode}";
                            var response = await httpClient.GetAsync(url);

                            if (response.IsSuccessStatusCode)
                            {
                                byte[] bytes = await response.Content.ReadAsByteArrayAsync();
                                string content;

                                try
                                {
                                    content = System.Text.Encoding.GetEncoding("GB18030").GetString(bytes);
                                }
                                catch
                                {
                                    content = System.Text.Encoding.UTF8.GetString(bytes);
                                }

                                var match = System.Text.RegularExpressions.Regex.Match(content, $@"v_{fullCode}=""[^~]*~([^~]*)~");
                                if (match.Success && match.Groups.Count > 1)
                                {
                                    stockName = match.Groups[1].Value;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"获取股票名称失败: {ex.Message}");
                        // 继续执行，不中断流程
                    }
                }

                using (var connection = _databaseService.GetConnection())
                {
                    await connection.OpenAsync();

                    // 检查是否已经添加过该股票
                    string checkQuery = "SELECT COUNT(*) FROM favorites WHERE user_id = @UserId AND stock_code = @StockCode";
                    using (var command = new MySqlCommand(checkQuery, connection))
                    {
                        command.Parameters.AddWithValue("@UserId", userId);
                        command.Parameters.AddWithValue("@StockCode", stockCode);
                        
                        long count = (long)await command.ExecuteScalarAsync();
                        if (count > 0)
                        {
                            return BadRequest(new { message = "该股票已在自选列表中" });
                        }
                    }

                    // 添加自选股票
                    string insertQuery = "INSERT INTO favorites (user_id, stock_code, stock_name) VALUES (@UserId, @StockCode, @StockName)";
                    using (var command = new MySqlCommand(insertQuery, connection))
                    {
                        command.Parameters.AddWithValue("@UserId", userId);
                        command.Parameters.AddWithValue("@StockCode", stockCode);
                        command.Parameters.AddWithValue("@StockName", stockName);
                        
                        await command.ExecuteNonQueryAsync();
                    }
                }

                return Ok(new { message = "添加自选成功" });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"添加自选失败: {ex.Message}");
                return StatusCode(500, new { message = "添加自选失败，请重试" });
            }
        }

        [HttpPost("remove-favorite")]
        public async Task<IActionResult> RemoveFavorite([FromBody] AddFavoriteRequest request)
        {
            // 检查用户是否已登录
            if (HttpContext.Session.GetInt32("UserId") == null)
            {
                return Unauthorized(new { message = "请先登录" });
            }

            if (string.IsNullOrEmpty(request.StockCode))
            {
                return BadRequest(new { message = "股票代码不能为空" });
            }

            int userId = HttpContext.Session.GetInt32("UserId").Value;
            string stockCode = request.StockCode;

            try
            {
                using (var connection = _databaseService.GetConnection())
                {
                    await connection.OpenAsync();

                    // 删除自选股票
                    string deleteQuery = "DELETE FROM favorites WHERE user_id = @UserId AND stock_code = @StockCode";
                    using (var command = new MySqlCommand(deleteQuery, connection))
                    {
                        command.Parameters.AddWithValue("@UserId", userId);
                        command.Parameters.AddWithValue("@StockCode", stockCode);
                        
                        int rowsAffected = await command.ExecuteNonQueryAsync();
                        if (rowsAffected == 0)
                        {
                            return NotFound(new { message = "未找到该自选股票" });
                        }
                    }
                }

                return Ok(new { message = "删除自选成功" });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"删除自选失败: {ex.Message}");
                return StatusCode(500, new { message = "删除自选失败，请重试" });
            }
        }

        [HttpGet("stock-info")]
        public async Task<IActionResult> GetStockInfo([FromQuery] string code)
        {
            if (string.IsNullOrEmpty(code))
            {
                return BadRequest(new { message = "股票代码不能为空" });
            }

            try
            {
                // 验证股票代码格式
                if (!System.Text.RegularExpressions.Regex.IsMatch(code, @"^\d{6}$"))
                {
                    return BadRequest(new { message = "股票代码格式不正确" });
                }

                // 判断股票市场
                string market;
                if (code.StartsWith("60") || code.StartsWith("68"))
                {
                    market = "sh"; // 上海证券交易所
                }
                else if (code.StartsWith("00") || code.StartsWith("30"))
                {
                    market = "sz"; // 深圳证券交易所
                }
                else
                {
                    market = "bj"; // 北京证券交易所
                }
                
                string fullCode = $"{market}{code}";

                // 使用代理服务器避免跨域问题
                string url = $"https://qt.gtimg.cn/q={fullCode}";
                string proxyUrl = $"/api/stock-proxy?url={Uri.EscapeDataString(url)}";
                
                using (var httpClient = new HttpClient())
                {
                    var response = await httpClient.GetAsync($"http://{Request.Host}{proxyUrl}");
                    
                    if (response.IsSuccessStatusCode)
                    {
                        string content = await response.Content.ReadAsStringAsync();
                        
                        // 解析股票名称
                        var match = System.Text.RegularExpressions.Regex.Match(content, $@"v_{fullCode}=""[^~]*~([^~]*)~");
                        if (match.Success && match.Groups.Count > 1)
                        {
                            string stockName = match.Groups[1].Value;
                            return Ok(new { code, name = stockName });
                        }
                    }
                }

                // 如果代理服务器请求失败，尝试直接请求
                using (var httpClient = new HttpClient())
                {
                    var response = await httpClient.GetAsync(url);

                    if (response.IsSuccessStatusCode)
                    {
                        // 获取响应内容
                        byte[] bytes = await response.Content.ReadAsByteArrayAsync();
                        string content;

                        try
                        {
                            // 尝试使用GB18030解码（腾讯财经API使用GBK编码）
                            content = System.Text.Encoding.GetEncoding("GB18030").GetString(bytes);
                        }
                        catch
                        {
                            // 如果GB18030不可用，则回退到UTF-8
                            content = System.Text.Encoding.UTF8.GetString(bytes);
                        }

                        // 解析股票名称
                        var match = System.Text.RegularExpressions.Regex.Match(content, $@"v_{fullCode}=""[^~]*~([^~]*)~");
                        if (match.Success && match.Groups.Count > 1)
                        {
                            string stockName = match.Groups[1].Value;
                            return Ok(new { code, name = stockName });
                        }
                    }

                    return NotFound(new { message = "未找到股票信息" });
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取股票信息失败: {ex.Message}");
                return StatusCode(500, new { message = "获取股票信息失败，请重试" });
            }
        }

        [HttpGet("trading-calendar")]
        public IActionResult GetTradingCalendar()
        {
            try
            {
                // 读取交易日历文件
                if (System.IO.File.Exists("交易日历.csv"))
                {
                    var lines = System.IO.File.ReadAllLines("交易日历.csv").Skip(1); // 跳过标题行
                    var tradingDays = lines.Where(line => !string.IsNullOrWhiteSpace(line)).Select(line => line.Trim()).ToList();
                    return Ok(new { tradingDays = tradingDays });
                }
                else
                {
                    return NotFound(new { message = "交易日历文件不存在" });
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取交易日历失败: {ex.Message}");
                return StatusCode(500, new { message = "获取交易日历失败，请重试" });
            }
        }

        [HttpGet("stock-proxy")]
        public async Task<IActionResult> ProxyRequest([FromQuery] string url)
        {
            if (string.IsNullOrEmpty(url))
            {
                Console.WriteLine("代理请求错误: URL为空");
                return BadRequest(new { message = "URL不能为空" });
            }

            Console.WriteLine($"收到代理请求: {url}");
            
            try
            {
                using (var httpClient = new HttpClient())
                {
                    // 设置超时时间
                    httpClient.Timeout = TimeSpan.FromSeconds(10);
                    
                    // 添加User-Agent头，模拟浏览器请求
                    httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
                    
                    Console.WriteLine($"开始发送代理请求: {url}");
                    var response = await httpClient.GetAsync(url);
                    Console.WriteLine($"代理请求响应状态码: {(int)response.StatusCode} {response.StatusCode}");
                    
                    if (response.IsSuccessStatusCode)
                    {
                        byte[] bytes = await response.Content.ReadAsByteArrayAsync();
                        string content = null;
                        bool encodingSuccess = false;

                        // 尝试使用不同的编码方式解析内容
                        try
                        {
                            // 首先尝试GBK编码
                            content = System.Text.Encoding.GetEncoding("GBK").GetString(bytes);
                            encodingSuccess = true;
                            Console.WriteLine("使用GBK编码解析成功");
                        }
                        catch (Exception)
                        {
                            try
                            {
                                // 然后尝试GB18030编码（GBK的超集）
                                content = System.Text.Encoding.GetEncoding("GB18030").GetString(bytes);
                                encodingSuccess = true;
                                Console.WriteLine("使用GB18030编码解析成功");
                            }
                            catch (Exception)
                            {
                                try
                                {
                                    // 最后尝试GB2312编码
                                    content = System.Text.Encoding.GetEncoding("GB2312").GetString(bytes);
                                    encodingSuccess = true;
                                    Console.WriteLine("使用GB2312编码解析成功");
                                }
                                catch (Exception encEx)
                                {
                                    Console.WriteLine($"所有中文编码解析失败: {encEx.Message}，尝试使用UTF-8");
                                    content = System.Text.Encoding.UTF8.GetString(bytes);
                                }
                            }
                        }
                        
                        // 记录返回的原始内容，用于调试
                        Console.WriteLine($"代理请求成功: {url}");
                        Console.WriteLine($"返回内容长度: {content.Length}");
                        Console.WriteLine($"编码解析成功: {encodingSuccess}");
                        
                        if (content.Length > 0)
                        {
                            Console.WriteLine($"返回内容前100个字符: {content.Substring(0, Math.Min(100, content.Length))}");
                            
                            // 检查是否包含乱码（通常表现为�符号）
                            if (content.Contains("�"))
                            {
                                Console.WriteLine("警告：内容中包含乱码字符，可能编码处理不正确");
                            }
                        }
                        else
                        {
                            Console.WriteLine("返回内容为空");
                        }
                        
                        // 直接返回内容，让前端处理格式差异
                        return Content(content, "text/plain", System.Text.Encoding.UTF8);
                    }
                    else
                    {
                        Console.WriteLine($"代理请求失败: {url}, 状态码: {(int)response.StatusCode} {response.StatusCode}");
                        Console.WriteLine($"响应内容: {await response.Content.ReadAsStringAsync()}");
                        return StatusCode((int)response.StatusCode, new { message = $"代理请求失败，状态码: {(int)response.StatusCode}" });
                    }
                }
            }
            catch (TaskCanceledException ex)
            {
                Console.WriteLine($"代理请求超时: {url}, 错误: {ex.Message}");
                return StatusCode(504, new { message = "代理请求超时，请重试" });
            }
            catch (HttpRequestException ex)
            {
                Console.WriteLine($"代理请求网络错误: {url}, 错误: {ex.Message}");
                return StatusCode(502, new { message = $"代理请求网络错误: {ex.Message}" });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"代理请求异常: {url}, 错误类型: {ex.GetType().Name}, 错误: {ex.Message}");
                Console.WriteLine($"异常堆栈: {ex.StackTrace}");
                return StatusCode(500, new { message = $"代理请求失败: {ex.Message}" });
            }
        }
    }
} 